# -*- coding: utf-8 -*
import xlrd
import json
import os
import yaml
import codecs


class Config:
    def __init__(self):
        self.excel_path = None
        self.export_code_path = None
        self.export_data_path = None
        self.export_code_type = None
        self.export_data_type = None


def export_json(config):
    files = get_excels(config)
    outputDir = config.export_data_path
    if(not os.path.exists(outputDir)):
        os.makedirs(outputDir)
    for file in files:
        xl = xlrd.open_workbook(file)
        for sheet in xl._sheet_list:
            # 以#号开始的表不导
            if(sheet.name.startswith("#")):
                continue
            print("\n--------> export json: " + sheet.name)
            # 第一行是数据类型，第二行是字段名，以#号开始的行和列均不参与导表
            if(sheet.nrows > 2):
                field_type_array = sheet.row_values(0)
                field_name_array = sheet.row_values(1)
                if(len(field_type_array) != (len)(field_name_array)):
                    print("type count is not equal to filed count")
                    return
                outputFile = codecs.open(
                    outputDir + "/" + sheet.name+".txt", 'w', 'utf-8')
                json_str = "["
                # 读取数据
                for row in range(2, sheet.nrows):
                    field_val_array = sheet.row_values(row)
                    # 以#号开始的行不导
                    if(str(field_val_array[0]).startswith("#")):
                        continue
                    json_str += "{"
                    col_count = len(field_val_array)
                    for col in range(col_count):
                        field_type = field_type_array[col]
                        field_name = field_name_array[col]
                        field_val = field_val_array[col]
                        # 如果单元格是number类型，先试着把数据转换为整型，避免python自动将其转换为浮点数
                        if(sheet.cell(row, col).ctype == 2 and int(field_val) == field_val):
                            field_val = int(field_val)
                        # 以#号开始的列不导
                        if(field_type.startswith("#")):
                            continue
                        if(is_int(field_type) or is_float(field_type) or is_long(field_type)):
                            json_str += "\"{0}\":{1}".format(
                                field_name, field_val)
                        elif(is_string(field_type)):
                            json_str += "\"{0}\":\"{1}\"".format(
                                field_name, field_val)
                        elif(is_int_array(field_type) or is_float_array(field_type) or is_long_array(field_type)):
                            field_val = str(field_val)
                            vals = field_val.split("_")
                            vals_json = "["
                            for i in range(len(vals)):
                                vals_json += vals[i]
                                if i != len(vals) - 1:
                                    vals_json += ","
                            vals_json += "]"
                            json_str += "\"{0}\":{1}".format(
                                field_name, vals_json)
                        elif(is_string_array(field_type)):
                            field_val = str(field_val)
                            vals = field_val.split("_")
                            vals_json = "["
                            for i in range(len(vals)):
                                vals_json += "\"{0}\"".format(vals[i])
                                if i != len(vals) - 1:
                                    vals_json += ","
                            vals_json += "]"
                            json_str += "\"{0}\":{1}".format(
                                field_name, vals_json)
                        elif(is_int_array_array(field_type) or is_float_array_array(field_type) or is_long_array_array(field_type)):
                            field_val = str(field_val)
                            first_array = field_val.split("|")
                            vals_json = "["
                            for k in range(len(first_array)):
                                vals_json += "["
                                vals = first_array[k].split("_")
                                for i in range(len(vals)):
                                    vals_json += vals[i]
                                    if i != len(vals) - 1:
                                        vals_json += ","
                                vals_json += "]"
                                if k != len(first_array) - 1:
                                    vals_json += ","
                            vals_json += "]"
                            json_str += "\"{0}\":{1}".format(
                                field_name, vals_json)
                        elif(is_string_array_array(field_type)):
                            field_val = str(field_val)
                            first_array = field_val.split("|")
                            vals_json = "["
                            for k in range(len(first_array)):
                                vals_json += "["
                                vals = first_array[k].split("_")
                                for i in range(len(vals)):
                                    vals_json += "\"{0}\"".format(vals[i])
                                    if i != len(vals) - 1:
                                        vals_json += ","
                                vals_json += "]"
                                if k != len(first_array) - 1:
                                    vals_json += ","
                            vals_json += "]"
                            json_str += "\"{0}\":{1}".format(
                                field_name, vals_json)
                        if(col != col_count - 1):
                            json_str += ","
                    json_str += "}"
                    if row != sheet.nrows - 1:
                        json_str += ","
                json_str += "]"
                print(json_str)
                outputFile.write(json_str)


def export_ts(config):
    files = get_excels(config)
    outputDir = config.export_code_path
    if(not os.path.exists(outputDir)):
        os.makedirs(outputDir)
    for file in files:
        xl = xlrd.open_workbook(file)
        for sheet in xl._sheet_list:
            # 以#号开始的表不导
            if(sheet.name.startswith("#")):
                continue
            print("\n--------> export ts: " + sheet.name)
            # 第一行是数据类型，第二行是字段名，以#号开始的行和列均不参与导表
            if(sheet.nrows > 2):
                field_type_array = sheet.row_values(0)
                field_name_array = sheet.row_values(1)
                if(len(field_type_array) != (len)(field_name_array)):
                    print("type count is not equal to filed count")
                    return
                outputFile = codecs.open(
                    outputDir + "/" + sheet.name+".ts", 'w', 'utf-8')
                code_str = "export class {0} {{\n".format(sheet.name)
                for col in range(len(field_type_array)):
                    field_type = field_type_array[col]
                    field_name = field_name_array[col]
                    if (is_int(field_type) or is_float(field_type) or is_long(field_type)):
                        code_str += "\treadonly {0}: number;\n".format(
                            field_name)
                    elif (is_string(field_type)):
                        code_str += "\treadonly {0}: string;\n".format(
                            field_name)
                    elif (is_int_array(field_type) or is_float_array(field_type) or is_long_array(field_type)):
                        code_str += "\treadonly {0}: Array<number>;\n".format(
                            field_name)
                    elif (is_string_array(field_type)):
                        code_str += "\treadonly {0}: Array<string>;\n".format(
                            field_name)
                    elif (is_int_array_array(field_type) or is_float_array_array(field_type) or is_long_array_array(field_type)):
                        code_str += "\treadonly {0}: Array<Array<number>>;\n".format(
                            field_name)
                    elif (is_string_array_array(field_type)):
                        code_str += "\treadonly {0}: Array<Array<string>>;\n".format(
                            field_name)
                code_str += "\tprivate static _dataList: Array<{0}> = new Array<{1}>();\n".format(
                    sheet.name, sheet.name)
                code_str += "\tprivate static _dataDic: {{[key: string]: {0}}} = {{}};\n".format(
                    sheet.name)
                code_str += "\tstatic loadjson(json: string) {\n"
                code_str += "\t\tthis._dataList = JSON.parse(json);\n"
                code_str += "\t\tfor (let i = 0; i < this._dataList.length; i++) {\n"
                code_str += "\t\t\tthis._dataDic[this._dataList[i].id] = this._dataList[i];\n"
                code_str += "\t\t}\n"
                code_str += "\t}\n\n"
                code_str += "\tstatic getElement(id: string) {\n"
                code_str += "\t\treturn this._dataDic[id];\n"
                code_str += "\t}\n\n"
                code_str += "\tstatic getDataList(): Array<{0}> {{\n".format(
                    sheet.name)
                code_str += "\t\treturn this._dataList;\n"
                code_str += "\t}\n"
                code_str += "}"
                print(code_str)
                outputFile.write(code_str)


def export_code(config):
    if config.export_code_type == "ts":
        export_ts(config)


def export_data(config):
    if config.export_data_type == "json":
        export_json(config)


def get_excels(config):
    excel_path = config.excel_path
    excel_files = []
    for root, dirs, files in os.walk(excel_path):
        for file in files:
            # 以#号开头的表不导出，以~开头的为临时文件
            if file.endswith(".xlsx") and not file.startswith("~") and not file.startswith("#"):
                excel_files.append(os.path.join(root, file))
    return excel_files


def export_table(config):
    print("========begin export========")
    export_code(config)
    export_data(config)
    print("\n========export table finished!========\n")


def is_int(filed_type):
    return filed_type == "int"


def is_float(filed_type):
    return filed_type == "float"


def is_long(filed_type):
    return filed_type == "long"


def is_string(filed_type):
    return filed_type == "string"


def is_int_array(filed_type):
    return filed_type == "int[]"


def is_float_array(filed_type):
    return filed_type == "float[]"


def is_long_array(filed_type):
    return filed_type == "long[]"


def is_string_array(filed_type):
    return filed_type == "string[]"


def is_int_array_array(filed_type):
    return filed_type == "int[][]"


def is_float_array_array(filed_type):
    return filed_type == "float[][]"


def is_long_array_array(filed_type):
    return filed_type == "long[][]"


def is_string_array_array(filed_type):
    return filed_type == "string[][]"


if __name__ == '__main__':
    with open('config.yaml', 'r') as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        for key, val in enumerate(data):
            print(val)
            config = Config()
            config.__dict__ = val
            export_table(config)
